package com.quanxiaoha.weblog.web.service.impl;

import com.quanxiaoha.weblog.common.domain.dos.UserDO;
import com.quanxiaoha.weblog.common.domain.dos.UserRoleDO;
import com.quanxiaoha.weblog.common.domain.mapper.UserMapper;
import com.quanxiaoha.weblog.common.domain.mapper.UserRoleMapper;
import com.quanxiaoha.weblog.common.mail.MailHelper;
import com.quanxiaoha.weblog.common.utils.Response;
import com.quanxiaoha.weblog.web.service.AuthService;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ThreadLocalRandom;

@Service
@Slf4j
public class AuthServiceImpl implements AuthService {

    private static final ConcurrentHashMap<String, CodeInfo> CODE_CACHE = new ConcurrentHashMap<>();
    private static final long CODE_TTL_MS = 10 * 60 * 1000; // 10 分钟

    @Autowired
    private MailHelper mailHelper;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private UserRoleMapper userRoleMapper;
    @Autowired
    private PasswordEncoder passwordEncoder;

    @Override
    public Response sendRegisterCode(String mail) {
        // 简单生成 6 位数字验证码
        String code = String.format("%06d", ThreadLocalRandom.current().nextInt(0, 1000000));
        long expireAt = System.currentTimeMillis() + CODE_TTL_MS;
        CODE_CACHE.put(mail, CodeInfo.builder().code(code).expireAt(expireAt).build());

        String title = "注册验证码";
        String html = String.format("<html><body><h2>您的注册验证码：</h2><h1>%s</h1><p>验证码有效期 10 分钟，请尽快完成注册。</p></body></html>", code);
        boolean ok = mailHelper.sendHtml(mail, title, html);
        if (!ok) {
            return Response.fail("验证码发送失败，请稍后重试");
        }
        return Response.success();
    }

    @Override
    public Response register(String mail, String password, String code) {
        // 校验验证码
        CodeInfo codeInfo = CODE_CACHE.get(mail);
        if (Objects.isNull(codeInfo)) {
            return Response.fail("请先获取验证码");
        }
        if (System.currentTimeMillis() > codeInfo.getExpireAt()) {
            CODE_CACHE.remove(mail);
            return Response.fail("验证码已过期，请重新获取");
        }
        if (!Objects.equals(codeInfo.getCode(), code)) {
            return Response.fail("验证码不正确");
        }

        // 判断用户是否已存在
        UserDO existed = userMapper.findByUsername(mail);
        if (Objects.nonNull(existed)) {
            return Response.fail("该邮箱已注册");
        }

        // 保存用户
        String encodePassword = passwordEncoder.encode(password);
        UserDO userDO = UserDO.builder()
                .username(mail)
                .password(encodePassword)
                .createTime(LocalDateTime.now())
                .updateTime(LocalDateTime.now())
                .isDeleted(false)
                .build();
        userMapper.insert(userDO);

        // 绑定默认角色：普通用户
        UserRoleDO roleDO = UserRoleDO.builder()
                .username(mail)
                .role("ROLE_VISITOR")
                .build();
        userRoleMapper.insert(roleDO);

        // 清理验证码
        CODE_CACHE.remove(mail);

        return Response.success();
    }

    @Data
    @Builder
    @NoArgsConstructor
    @AllArgsConstructor
    private static class CodeInfo {
        private String code;
        private long expireAt;
    }
} 